package net.sf.xoperator.ui.aiml;

import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Properties;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import bitoflife.chatterbean.AliceBot;
import bitoflife.chatterbean.parser.AliceBotParser;
import bitoflife.chatterbean.parser.AliceBotParserException;
import bitoflife.chatterbean.util.Searcher;

/**
 * This class takes some code of the GPL licensed class
 * <code>bitoflife.chatterbean.Chatterbean</code> to construct an AliceBot
 * without creating any user interface, as opposed to the original
 * implementation.
 */
public class AliceBotFactory {
	
	private final Log log = LogFactory.getLog(this.getClass());
	
	private String path;


	private AliceBot bot;
	
	/**
	 * Creates a new AliceBotFactory. The factory will be configured according 
	 * to the configuration file, located by the <code>path</code> parameter.
	 * The AliceBots will be of the 
	 * @param path
	 * @param aliceBotClass
	 */
	
	public AliceBotFactory(String path) {
		super();
		this.path = path;
	}
	/**
	 * Fills an emtpy AliceBot instance with the information found in the
	 * location of the <code>path</code>.
	 * 
	 * @param path
	 *            the location of an Alice Bot configuration file.
	 * @throws AliceBotParserException
	 */
	public AliceBotExternal getAliceBot() throws AliceBotParserException {
		try {
			
			AliceBotExternal bot = new AliceBotExternal();
			

			Properties properties = new Properties();
			properties.loadFromXML(new FileInputStream(this.path));

			String root = path.substring(0, path.lastIndexOf(System.getProperty("file.separator")) + 1);

			String categories = root + properties.getProperty("categories");
			String logs = properties.getProperty("logs");

			InputStream context = newResourceStream("context", root, properties
					.getProperty("context"));
			InputStream splitters = newResourceStream("splitters", root,
					properties.getProperty("splitters"));
			InputStream substitutions = newResourceStream("substitutions",
					root, properties.getProperty("substitutions"));

			Searcher searcher = new Searcher();
			AliceBotParser botParser = new AliceBotParser();
			botParser.contextClass(BlackBoardContext.class);
			botParser.parse(bot, context, splitters,
					substitutions, searcher.search(categories, ".*\\.aiml"));
			
			bot.registerExternalListener(new TemplateListener());
			bot.registerExternalListener(new GroovyListener(path.substring(0, path.lastIndexOf(System.getProperty("file.separator"))) +System.getProperty("file.separator")  +"templates"));
			return bot;
			
		} catch (AliceBotParserException e) {
			throw e;
		} catch (Exception e) {
			throw new AliceBotParserException(e);
		}
	}
	
	/**
	 * opens the resource files.
	 * @param resource
	 * @param root
	 * @param path
	 * @return
	 * @throws Exception
	 */
	 private InputStream newResourceStream(String resource, String root, String path) throws Exception
	  {
	    if (root == null || path == null)
	      throw new IllegalArgumentException(
	        "Invalid path elements for retrieving " + resource + ": root(" + root + "), path(" + path + ")");
	    
	    path = root + path;
	    
	    try
	    {
	      return new FileInputStream(path);
	    }
	    catch (Exception e)
	    {
	      throw new Exception("Error while retrieving " + resource + ": " + path, e);
	    }
	  }

	
	  
	

}
